#include "TankWar.h"
#include "Tank.h"
#include "dkgl.h"
#include "dkglTimer.h"
#include <sstream>


using namespace DKGL;
using namespace OIS;

struct UserInput
{
	unsigned int _time;
	bool	_active;
};

typedef std::map<int, UserInput> UserInputMap;
UserInputMap UserInputs;







void TankWar::enter()
{
	initScene();

	UserInputs[KC_UP]._active = false;
	UserInputs[KC_DOWN]._active = false;
	UserInputs[KC_LEFT]._active = false;
	UserInputs[KC_RIGHT]._active = false;
}

void TankWar::exit()
{
	clearScene();
}

void TankWar::pause()
{

}
	
void TankWar::resume()
{
}


void TankWar::keyPressed( const KeyEvent &e )
{
	UserInputMap::const_iterator iter(UserInputs.find(e.key));

	if (iter!=UserInputs.end())
	{
		iter->second._active = true;
		iter->second._time = GlobalTimer().elapsed_msec();
	}

	/*if ()

	switch (e.key)
	{
	case KC_RIGHT:
		tankNode->yaw(1);
		break;

	case KC_LEFT:
		tankNode->yaw(-1);
		break;

	case KC_UP:
		tankNode->moveForward(1.0f);
		break;

	case KC_DOWN:
		tankNode->moveForward(-1.0f);
		break;
	}*/
}


void TankWar::keyReleased( const KeyEvent &e )
{
	UserInputMap::const_iterator iter(UserInputs.find(e.key));

	if (iter!=UserInputs.end())
	{
		iter->second._active = false;
	}
}

void TankWar::mouseMoved( const MouseEvent &e )
{

}

void TankWar::mousePressed( const MouseEvent &e, MouseButtonID id )
{

}

void TankWar::mouseReleased( const MouseEvent &e, MouseButtonID id )
{

}

void TankWar::frameStarted(float)
{
	// collect client input and fire event
	UserInputMap::iterator iter(UserInputs.begin());
	UserInputMap::iterator end(UserInputs.begin());
	unsigned int current;
	unsigned int duration;

	for (;iter!=end;++iter)
	{
		if (iter->second._time)
		{
			duration = iter->second._time - current;

			if (iter->second._active)
			{
				iter->second._time = current;
			}
			else
			{
				iter->second._time = 0;
			}

			// fire event
			UserCmdEvent.notify()

		}
	}
}

void TankWar::frameEnded(float)
{

}

void TankWar::initScene()
{
	// creare scene and get root
	ScenePtr scenePtr = SceneManager::instance().createScene("TankWarScene");
	Root& root = scenePtr->getRoot();

	tankNode = MovablePtr(new Tank());

	// grid
	MovablePtr gridNode = MovablePtr(new Movable("GridNode"));
	MaterialPtr yellow = MaterialPtr(new Material("Yellow"));
	yellow->setColor(Colorf::YELLOW);
	yellow->setRenderMode(RM_WIRE);
	primitive::Grid* grid = new primitive::Grid("Grid", 150, 150, 30, 30);
	grid->setMaterial(0, yellow);
	gridNode->addDrawable(grid);
	gridNode->pitch(90.0f);
	
    root.addChild(gridNode);
	root.addChild(tankNode);

	cameraPtr = scenePtr->createCamera("Camera");
	cameraPtr->bindViewport(g_ViewportMgr.getViewportPtr());

	cameraPtr->pitch(-90);
	cameraPtr->moveForward(-40);
	cameraPtr->rotate(45.0f, DKGL::Vector3::UNIT_X, DKGL::GLOBAL);

	tankNode->addChild(cameraPtr);

	// skybox
	//skybox = new primitive::Box("Skybox", 30, 30, 30);
	//MaterialPtr skyboxMat = MaterialPtr(new Material("SkyBoxMat"));
	//skyboxMat->setColor(Colorf::WHITE);
	//skyboxMat->enableDepthTest(false);
	//skyboxMat->setFrontFaceWinding(FFW_CW);

	//TexturePtr skyboxTex = TexturePtr(new Texture());
	//skyboxTex->load("skybox.png");
	//skyboxMat->setTexture(skyboxTex);
	//skybox->setMaterial(0, skyboxMat);
}




#if 0

void TankWarApp::OnPaint()
{
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    DrawList::Instance().flush();

	g_FontMgr.begin(g_ViewportMgr.getViewport(0));
	{
	}
	g_FontMgr.end();
}


void TankWarApp::OnSize(WORD width, WORD height)
{
	g_ViewportMgr.getViewportPtr()->onSize(
		intRect2D(0, 0, static_cast<int>(width), static_cast<int>(height)),
		DKGL::DefaultVpSizer());
}


void TankWarApp::OnTime()
{
    camera->look();
	
	float m[16];

	glGetFloatv(GL_MODELVIEW_MATRIX, m);
    m[12] = 0; m[13] = 0; m[14] = 0;
	skybox->setWorldTransformation(m);
	skybox->render();
    _root->updateTransform();
	physics::EvalOrientedBoundingBoxCollsion();
}

struct KeyButton
{
	int _keyCode;
	float _time;
};

KeyButton forward;
KeyButton backward;
KeyButton turnLeft;
KeyButton turnRight;


	
void TankWarApp::KeyDown()
{
	float fov;

	if (mKeys[DK_1])
	{
		fov = camera->getFov();
		camera->setFov(++fov);
	}
	else if (mKeys[DK_2])
	{
		fov = camera->getFov();
		camera->setFov(--fov);
	}
	else if (mKeys[DK_3])
	{
		cameraNode->rotate(1, Vector3::UNIT_X, GLOBAL);
	}
	else if (mKeys[DK_4])
	{
		cameraNode->rotate(-1, Vector3::UNIT_X, GLOBAL);
	}
	else if(mKeys[DK_W])
		cameraNode->moveForward(1);
	else if(mKeys[DK_S])
		cameraNode->moveForward(-1);
	else if(mKeys[DK_A])
		cameraNode->moveRight(-1);
	else if(mKeys[DK_D])
		cameraNode->moveRight(1);
    else if(mKeys[DK_Q])
		cameraNode->moveUp(1);
    else if(mKeys[DK_E])
		cameraNode->moveUp(-1);
	else if (mKeys[DK_RIGHT])
		tankNode->yaw(1);
	else if (mKeys[DK_LEFT])
		tankNode->yaw(-1);
	else if (mKeys[DK_UP])
	{
		forward._time = getTimeInSec();
		tankNode->moveForward(1.0f);
	}
	else if (mKeys[DK_DOWN])
		tankNode->moveForward(-1.0f);
}

#endif